package command

import (
	"flag"
	"fmt"
	"go-toy/database/orm"
	"go-toy/util"
	"sync"

	"gorm.io/gen"
)

// This flag is used for building database migrater by command line.
func init() {
	migrater := flag.String("migrater", "none", "Filed for building database migrater, options: none, all, dbname.")

	flag.Parse()

	if *migrater != "none" {
		if *migrater == "all" {
			generateInstance().GenerateAllTable()
			util.PrintlnSuccess("Migrater all tables done.")
		} else {
			generateInstance().GenerateModel(*migrater)
			util.PrintlnSuccess(fmt.Sprintf("Migrater %s table done.", *migrater))
		}
	}
}

type GenerateCommand struct {
	G *gen.Generator
}

// GenerateAllTable generates all models
func (c *GenerateCommand) GenerateAllTable() {
	c.G.GenerateAllTable()
	c.Execute()
}

// GenerateModel generates one model
func (c *GenerateCommand) GenerateModel(dbName string) {
	c.G.GenerateModel(dbName)
	c.Execute()
}

// Execute generates
func (c *GenerateCommand) Execute() {
	c.G.Execute()
}

var (
	once     sync.Once
	instance *GenerateCommand
)

// GenerateInstance returns a singleton instance of GenerateCommand
func generateInstance() *GenerateCommand {
	once.Do(func() {
		instance = &GenerateCommand{}
		instance.G = gen.NewGenerator(gen.Config{
			OutPath:      "./query",
			ModelPkgPath: "./migrater",
			Mode:         gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode
		})

		instance.G.UseDB(orm.DB) // reuse your gorm db
	})
	return instance
}
